package com.netty.rpc.runner;

import org.springframework.beans.BeansException;
import org.springframework.boot.CommandLineRunner;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import org.springframework.stereotype.Component;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;

//@Component
public class RpcServer implements CommandLineRunner, ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void run(String... args) throws Exception {
        ServerSocket serverSocket = new ServerSocket(8081);
        while (true) {
            Socket socket = serverSocket.accept();
            new Thread(() -> {
                try {

                    ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
                    String simpleName = inputStream.readUTF();
                    String className = inputStream.readUTF();
                    String methodName = inputStream.readUTF();
                    Class<?>[] parameterTypes = (Class<?>[]) inputStream.readObject();
                    Object[] params = (Object[]) inputStream.readObject();

                    //不使用spring 不用spi如何获取一个接口的所有实现类
                    //Class service = Class.forName(className);


                    Object bean = applicationContext.getBean(simpleName);
                    Method method = bean.getClass().getMethod(methodName, parameterTypes);
                    Object result = method.invoke(bean, params);
                    ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
                    outputStream.writeObject(result);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext application) throws BeansException {
        applicationContext = application;
    }
}
